/** Description of GraphWeek.java 
 *
 * @author panther
 * Jayant Pratim Saikia
 * jay.saikia@gmail.com
 *
 */
package com.panther.awp.android.smoker.activities.graphs;

import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

import android.app.Activity;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.androidplot.Plot;
import com.androidplot.series.XYSeries;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.LineAndPointRenderer;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYStepMode;
import com.panther.awp.android.smoker.R;
import com.panther.awp.android.smoker.database.AbstractDbAdapter;
import com.panther.awp.android.smoker.database.MyDBWrapper;
import com.panther.awp.android.smoker.logical.NumberComparator;

public class GraphWeek extends Activity {
	
	private XYPlot mWeekPlot;
	private XYPlot mWeekPricePlot;
	private TextView myCountText;
	private MyDBWrapper mDBWrapper;
	private TreeMap<Number, Number> dailyCiggCount;
	private TreeMap<Number, Number> dailyCost;
	private XYSeries mWeekSeries;
	private XYSeries mWeekPriceSeries;
	private int totalCount = 0;
	private float totalCost = 0f;
	private int lowerlimitCount = Integer.MAX_VALUE;
	private int upperlimitCount = 0;
	private float lowerlimitCost = Float.MAX_VALUE;
	private float upperlimitCost = 0f;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.thisweekplot);
		mDBWrapper = MyDBWrapper.getInstance(getApplicationContext());
		mWeekPlot = (XYPlot) findViewById(R.id.myWeekCountPlot);
		mWeekPricePlot = (XYPlot) findViewById(R.id.myWeekPricePlot);
		myCountText = (TextView) findViewById(R.id.week_Smoked_Cigs);
		getData();
		mWeekPlot.addSeries(mWeekSeries, LineAndPointRenderer.class, new LineAndPointFormatter(Color.rgb(0, 200, 0), Color.rgb(200, 0, 0), Color.argb(100, 0, 200, 0)));
		mWeekPricePlot.addSeries(mWeekPriceSeries, LineAndPointRenderer.class, new LineAndPointFormatter(Color.rgb(0, 200, 0), Color.rgb(200, 0, 0), Color.argb(100, 0, 200, 0)));
		setPlotProperties();
		myCountText.setText("You have smoked " + totalCount + " cigarettes and it has cost you " + totalCost + " bucks.");
	}

	private void setPlotProperties() {
		mWeekPlot.setDomainBoundaries(1, 7, BoundaryMode.FIXED);
		mWeekPlot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1);
		mWeekPlot.setTicksPerRangeLabel(1);
		mWeekPlot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1);
		mWeekPlot.setRangeBoundaries(lowerlimitCount == 0 ? 0 : lowerlimitCount - 1, upperlimitCount + 1, BoundaryMode.FIXED);
		mWeekPlot.setDomainValueFormat(new BrandIndexFormat());
		mWeekPlot.setRangeValueFormat(new DecimalFormat("#"));
		mWeekPlot.setDomainLabel("Brands");
		mWeekPlot.getDomainLabelWidget().pack();
		mWeekPlot.setRangeLabel("# of Ciggaretes");
		mWeekPlot.getRangeLabelWidget().pack();
		mWeekPlot.setGridPadding(10, 0, 10, 0);
		mWeekPlot.setPlotMargins(0, 0, 0, 0);
		//mWeekPlot.setPlotPadding(0, 0, 0, 0);
		mWeekPlot.getGraphWidget().setMarginTop(2);
		mWeekPlot.getGraphWidget().setMarginRight(2);
		mWeekPlot.setBorderStyle(Plot.BorderStyle.SQUARE, null, null);
		mWeekPlot.disableAllMarkup();
    	
    	mWeekPricePlot.setDomainBoundaries(1, 7, BoundaryMode.FIXED);
        mWeekPricePlot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 1);
        mWeekPricePlot.setTicksPerRangeLabel(4);
        mWeekPricePlot.setRangeBoundaries(lowerlimitCost == 0 ? 0 : lowerlimitCost - 1, upperlimitCost + 1, BoundaryMode.FIXED);
        mWeekPricePlot.setDomainValueFormat(new BrandIndexFormat());
        mWeekPricePlot.setDomainLabel("Brands");
        mWeekPricePlot.getDomainLabelWidget().pack();
        mWeekPricePlot.setRangeLabel("Money Paid");
        mWeekPricePlot.getRangeLabelWidget().pack();
        mWeekPricePlot.setGridPadding(10, 0, 10, 0);
        mWeekPricePlot.setPlotMargins(0, 0, 0, 0);
		//mWeekPricePlot.setPlotPadding(0, 0, 0, 0);
        mWeekPricePlot.getGraphWidget().setMarginTop(2);
        mWeekPricePlot.getGraphWidget().setMarginRight(2);
        mWeekPricePlot.setBorderStyle(Plot.BorderStyle.SQUARE, null, null);
        mWeekPricePlot.disableAllMarkup();
		
	}

	private void getData() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		cal.set(Calendar.MILLISECOND, 999);
		Date todayEndDate = new Date(cal.getTimeInMillis());
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 1);
		Date weekStartDate = new Date(cal.getTimeInMillis());
		Cursor cursor = mDBWrapper.getmDTDbHelper().fetchInBetweenDate(weekStartDate, todayEndDate);
		startManagingCursor(cursor);
		
		dailyCiggCount = new TreeMap<Number, Number>();
		dailyCost = new TreeMap<Number, Number>();
		
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			float cost = cursor.getFloat(cursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_COST));
			int count = cursor.getInt(cursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_NO_OF_CIGGS));
			String startDateTimeStr = cursor.getString(cursor.getColumnIndexOrThrow(AbstractDbAdapter.DT_STARTDATE));
			Date smokeDateStart = null;
			try {
				smokeDateStart = AbstractDbAdapter.DATE_FORMAT.parse(startDateTimeStr);
			} catch (ParseException e) {
			}
			if(smokeDateStart != null) {
				cal.setTime(smokeDateStart);
				int thisSmokeDay = cal.get(Calendar.DAY_OF_WEEK);
				if(dailyCiggCount.containsKey(thisSmokeDay)) {
					dailyCiggCount.put(thisSmokeDay, dailyCiggCount.get(thisSmokeDay).intValue() + count);
					dailyCost.put(thisSmokeDay, dailyCost.get(thisSmokeDay).floatValue() + cost);
				} else {
					dailyCiggCount.put(thisSmokeDay, count);
					dailyCost.put(thisSmokeDay, cost);
				}
				
				totalCount += count;
				totalCost += cost;
			} else {
				Log.w(getCallingPackage(), "Wrong Data in database or something went horribly wrong.");
			}
			
			cursor.moveToNext();
		}
		cal.setTime(todayEndDate);
		insertEmptyDaysWithZeros(cal.get(Calendar.DAY_OF_WEEK));
		
		List<Number> dailyCountVals = new ArrayList<Number>(dailyCiggCount.values());
		List<Number> dailyIdVals = new ArrayList<Number>(dailyCiggCount.keySet());
		List<Number> dailyCostVals = new ArrayList<Number>(dailyCost.values());
		mWeekSeries = new SimpleXYSeries(dailyIdVals, dailyCountVals, "Daily Count");
		mWeekPriceSeries = new SimpleXYSeries(dailyIdVals, dailyCostVals, "Daily Cost");
		
		lowerlimitCount = Collections.min(dailyCountVals, NumberComparator.getInstance()).intValue();
		upperlimitCount = Collections.max(dailyCountVals, NumberComparator.getInstance()).intValue();
		
		upperlimitCost = Collections.max(dailyCostVals, NumberComparator.getInstance()).floatValue();
		lowerlimitCost = Collections.min(dailyCostVals, NumberComparator.getInstance()).floatValue();
	}

	private void insertEmptyDaysWithZeros(int today) {
		if(!dailyCiggCount.containsKey(Calendar.SUNDAY)) {
			dailyCiggCount.put(Calendar.SUNDAY, 0);
			dailyCost.put(Calendar.SUNDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.MONDAY) && (Calendar.MONDAY <= today)) {
			dailyCiggCount.put(Calendar.MONDAY, 0);
			dailyCost.put(Calendar.MONDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.TUESDAY) && (Calendar.TUESDAY <= today)) {
			dailyCiggCount.put(Calendar.TUESDAY, 0);
			dailyCost.put(Calendar.TUESDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.WEDNESDAY) && (Calendar.WEDNESDAY <= today)) {
			dailyCiggCount.put(Calendar.WEDNESDAY, 0);
			dailyCost.put(Calendar.WEDNESDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.THURSDAY) && (Calendar.THURSDAY <= today)) {
			dailyCiggCount.put(Calendar.THURSDAY, 0);
			dailyCost.put(Calendar.THURSDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.FRIDAY) && (Calendar.FRIDAY <= today)) {
			dailyCiggCount.put(Calendar.FRIDAY, 0);
			dailyCost.put(Calendar.FRIDAY, 0.0);
		}
		if(!dailyCiggCount.containsKey(Calendar.SATURDAY) && (Calendar.SATURDAY <= today)) {
			dailyCiggCount.put(Calendar.SATURDAY, 0);
			dailyCost.put(Calendar.SATURDAY, 0.0);
		}
	}

	private class BrandIndexFormat extends Format {

		private static final long serialVersionUID = 5133698491470068632L;

		@Override
		public StringBuffer format(Object object, StringBuffer buffer, FieldPosition field) {
			Number num = (Number) object;
			int roundNum = (int) (num.floatValue());
			switch (roundNum) {
			case Calendar.SUNDAY:
				buffer.append("Sunday");
				break;
			case Calendar.MONDAY:
				buffer.append("Monday");
				break;
			case Calendar.TUESDAY:
				buffer.append("Tuesday");
				break;
			case Calendar.WEDNESDAY:
				buffer.append("Wednesday");
				break;
			case Calendar.THURSDAY:
				buffer.append("Thursday");
				break;
			case Calendar.FRIDAY:
				buffer.append("Friday");
				break;
			case Calendar.SATURDAY:
				buffer.append("Saturday");
				break;
			default:
				break;
			}
			return buffer;
		}

		@Override
		public Object parseObject(String string, ParsePosition position) {
			return null;
		}
		
	}

}
